package com.mobilesalon.activity;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.content.Intent;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.os.Bundle;
import android.provider.ContactsContract.Contacts;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.SimpleCursorAdapter;
import android.widget.SimpleCursorAdapter.ViewBinder;
import android.widget.TextView;

import com.mobilesalon.MobileSalonFactory;
import com.mobilesalon.R;
import com.mobilesalon.business.ServiceClientManager;
import com.mobilesalon.contact.ContactProvider;
import com.mobilesalon.model.AppointmentBean;
import com.mobilesalon.model.Client;
import com.mobilesalon.model.ServiceBean;
import com.mobilesalon.model.ServiceClientBean;
import com.mobilesalon.widget.picker.NumberPicker;
import com.mobilesalon.widget.picker.NumberPicker.OnChangedListener;

public class ServiceAdder extends ListActivity {
	private static final String TAG = ServiceAdder.class.getName();

	static final int ACTIVITY_RESULT_OK = 1;

	static final int PICK_CONTACT = 1;
	static final int DIALOG_SHOW_SERVICE = 2;
	static final int DIALOG_ERROR_CLIENT_NOT_SELECTED = 3;
	static final int DIALOG_ERRORMSG_CLIENT_NOT_SELECTED = R.string.dialog_error_client_not_selected;
	static final int DIALOG_ERROR_SERVICES_NOT_SELECTED = 4;
	static final int DIALOG_ERRORMSG_SERVICES_NOT_SELECTED = R.string.dialog_error_services_not_selected;

	private TextView textClient;

	// model
	private Client client;
	private List<ServiceBean> serviceBeans;
	private AppointmentBean appointmentBean;

	// business services
	private ServiceClientManager serviceClientManager;
	private ContactProvider contactProvider;
	
	// dialog service selection
	private boolean[] isSelectedServices;
	private long[] servicePrices;
	private String[] serviceNames;
	private long[] serviceIds;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		Log.d(TAG, "Start Activity: ServiceAdder");
		super.onCreate(savedInstanceState);

		// business services
		serviceClientManager = MobileSalonFactory.getServiceClientManager();
		contactProvider = MobileSalonFactory.getContactProvider();
		
		setContentView(R.layout.service_adder);

		// get UI objects
		textClient = (TextView) findViewById(R.id.service_adder_layout_textClient);

		//
		// Check data passed to activity
		//
		this.appointmentBean = (AppointmentBean) this.getIntent().getParcelableExtra(
				"appointmentBean");

		if (appointmentBean == null) {
			Log.e(TAG, "Start Activity: ServiceAdder");
			throw new IllegalStateException(
					"An object of type AppointmentBean(\"appointmentBean\")must be passed to this activity");
		}

		
		// by default the client of the service is the client of the
		// appointment
		
		this.client = new Client(appointmentBean.getClientLookupKey(), appointmentBean.getClientDisplayName());
		textClient.setText(appointmentBean.getClientDisplayName());
		
		this.retreiveServiceAndFillDialogData();
	}

	private void retreiveServiceAndFillDialogData() {
		// retrieve services
		List<ServiceBean> availableServices = serviceClientManager.fetchServices();

		isSelectedServices = new boolean[availableServices.size()];
		servicePrices = new long[availableServices.size()];
		serviceNames = new String[availableServices.size()];
		serviceIds = new long[availableServices.size()];
		int i = 0;
		for (ServiceBean service : availableServices) {
			isSelectedServices[i] = false;
			servicePrices[i] = service.getPrice();
			serviceNames[i] = service.getServiceName();
			serviceIds[i] = service.getServiceId();
			i++;

		}

	}

	public void onPickClientButton(View view) {
		// Create an intent to "pick" a contact, as defined by the content
		// provider URI

		Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
		startActivityForResult(intent, PICK_CONTACT);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// If the request went well (OK) and the request was
		// PICK_CONTACT_REQUEST
		if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT) {
			// Perform a query to the contact's content provider for the
			// contact's details
			Cursor cursor = getContentResolver().query(data.getData(),
					new String[] { Contacts._ID, Contacts.DISPLAY_NAME, Contacts.LOOKUP_KEY },
					null, null, null);
			if (cursor.moveToFirst()) { // True if the cursor is not empty
				String name = cursor.getString(cursor.getColumnIndex(Contacts.DISPLAY_NAME));
				String lookupKey = cursor.getString(cursor.getColumnIndex(Contacts.LOOKUP_KEY));

				this.client = new Client(lookupKey, name);

				textClient.setText(name);

			}
			cursor.close();
		}
	}

	public void onPickServiceButton(View view) {

		// open dialog box to select the service
		this.showDialog(ServiceAdder.DIALOG_SHOW_SERVICE);

	}

	@Override
	protected Dialog onCreateDialog(int id) {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);

		switch (id) {

		case ServiceAdder.DIALOG_SHOW_SERVICE:

			Arrays.fill(this.isSelectedServices, false);

			builder.setTitle("Selectionnez les services")
					.setCancelable(true)
					.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int id) {
							fillServiceSelectionList();
						}
					})
					.setMultiChoiceItems(this.serviceNames, this.isSelectedServices,
							new OnMultiChoiceClickListener() {
								public void onClick(DialogInterface dialog, int which,
										boolean isChecked) {
									isSelectedServices[which] = isChecked;

								}
							}

					);
			break;
		case ServiceAdder.DIALOG_ERROR_CLIENT_NOT_SELECTED:
			builder.setTitle(DIALOG_ERRORMSG_CLIENT_NOT_SELECTED);
			builder.setPositiveButton("OK", null);
			break;

		case ServiceAdder.DIALOG_ERROR_SERVICES_NOT_SELECTED:
			builder.setTitle(DIALOG_ERRORMSG_SERVICES_NOT_SELECTED);
			builder.setPositiveButton("OK", null);
		}
		AlertDialog alert = builder.create();
		return alert;
	}

	protected void fillServiceSelectionList() {
		// list
		MatrixCursor selectedServiceCursor = new MatrixCursor(new String[] { "_id", "serviceName",
				"price" });
		this.startManagingCursor(selectedServiceCursor);

		// refresh list
		for (int i = 0; i < isSelectedServices.length; i++) {
			if (isSelectedServices[i]) {
				selectedServiceCursor.addRow(new Object[] { serviceIds[i], serviceNames[i],
						servicePrices[i] });
			}

		}

		// Create a mapping between database columns and layout fields
		String[] from = new String[] { "serviceName", "price" };
		int[] to = new int[] { R.id.service_adder_row_service, R.id.timepicker_input };

		// Create a cursor adapter and set it to display using a row layout
		SimpleCursorAdapter notesAdapter = new SimpleCursorAdapter(this,
				R.layout.service_adder_row, selectedServiceCursor, from, to);
		notesAdapter.setViewBinder(new ViewBinder() {

			public boolean setViewValue(View view, final Cursor cursor, int columnIndex) {
				if (columnIndex == cursor.getColumnIndex("price")) {
					EditText nbrPickerText = (EditText) view.findViewById(R.id.timepicker_input);
					long price = cursor.getLong(columnIndex);
					nbrPickerText.setText(String.valueOf(price));
					NumberPicker nbrPicker = (NumberPicker) nbrPickerText.getParent();
					nbrPicker.setOnChangeListener(new OnChangedListener() {
						public void onChanged(NumberPicker picker, int oldVal, int newVal) {
							Log.d(TAG, "Value changed:" + newVal);
							long currentServiceId = cursor.getLong(cursor.getColumnIndex("_id"));
							for (int i = 0; i < serviceIds.length; i++) {
								if (serviceIds[i] == currentServiceId) {
									servicePrices[i] = newVal;
									break;
								}
							}
						}
					});
					return true;
				}
				return false;
			}
		});

		this.setListAdapter(notesAdapter);
	}

	public void onChanged(NumberPicker picker, int oldVal, int newVal) {
		// TODO Auto-generated method stub

	}

	public void onSaveButton(View view) {
		Log.d(TAG, "save service");

		// validation
		if (client == null) {
			this.showDialog(ServiceAdder.DIALOG_ERROR_CLIENT_NOT_SELECTED);
			return;
		}
		
		if( ! appointmentBean.isIsStored()){
			// appointment not yet saved in db
			this.appointmentBean = serviceClientManager.add(appointmentBean);
		}

		final List<ServiceClientBean> serviceClientBeans = new ArrayList<ServiceClientBean>(
				isSelectedServices.length);

		for (int i = 0; i < isSelectedServices.length; i++) {
			if (isSelectedServices[i]) {
				ServiceClientBean serviceClientBean = new ServiceClientBean(Calendar.getInstance(),
						this.client, new ServiceBean(this.serviceIds[i]),
						this.appointmentBean.getId(), this.servicePrices[i]);
				serviceClientBeans.add(serviceClientBean);
			}

		}

		if (serviceClientBeans.size() == 0) {
			this.showDialog(ServiceAdder.DIALOG_ERROR_SERVICES_NOT_SELECTED);
			return;
		}

		// services creation
		for (ServiceClientBean serviceClientBean : serviceClientBeans) {
			serviceClientManager.add(serviceClientBean);
		}

		Intent intent = new Intent(getApplicationContext(), ServiceAdder.class);
		intent.putExtra("appointmentBean", appointmentBean);
		
		setResult(RESULT_OK,intent);
		this.finish();
	}

}